package com.coffee.order.service.inquire.impl;

import com.coffee.admin.api.supplier.query.SupplierSystemDeployQuery;
import com.coffee.admin.service.merchant.bean.Merchant;
import com.coffee.admin.service.merchant.dao.MerchantDao;
import com.coffee.admin.service.supplier.bean.Supplier;
import com.coffee.admin.service.supplier.bean.SupplierSystemDeploy;
import com.coffee.admin.service.supplier.dao.SupplierDao;
import com.coffee.admin.service.supplier.dao.SupplierSystemDeployDao;
import com.coffee.core.entity.Page;
import com.coffee.core.entity.PagerInfo;
import com.coffee.core.enums.*;
import com.coffee.core.exception.BusinessException;
import com.coffee.core.exception.ValidateBusinessException;
import com.coffee.core.util.BeanUtilExt;
import com.coffee.core.util.DTOUtils;
import com.coffee.core.util.DateUtil;
import com.coffee.core.util.StringUtil;
import com.coffee.order.api.inquire.query.InquireOrderTestingQuery;
import com.coffee.order.api.inquire.req.CreateTestingOrderReq;
import com.coffee.order.api.inquire.req.InquireOrderTestingReq;
import com.coffee.order.api.inquire.result.InquireOrderLogResult;
import com.coffee.order.api.inquire.result.InquireOrderTestingResult;
import com.coffee.order.api.inquire.service.InquireOrderTestingService;
import com.coffee.order.api.sku.result.OrderResult;
import com.coffee.order.service.inquire.bean.InquireOrder;
import com.coffee.order.service.inquire.bean.InquireOrderLog;
import com.coffee.order.service.inquire.bean.InquireOrderTesting;
import com.coffee.order.service.inquire.dao.InquireOrderDao;
import com.coffee.order.service.inquire.dao.InquireOrderLogDao;
import com.coffee.order.service.inquire.dao.InquireOrderTestingDao;
import com.coffee.order.service.sku.bean.Order;
import com.coffee.order.service.sku.dao.OrderDao;
import com.coffee.sku.api.inquire.query.InquireSkuTestingMessageQuery;
import com.coffee.sku.api.inquire.result.InquireSalesInformationResult;
import com.coffee.sku.api.inquire.result.InquireSkuTestingMessageResult;
import com.coffee.sku.service.inquire.bean.InquireSalesInformation;
import com.coffee.sku.service.inquire.bean.InquireSkuContent;
import com.coffee.sku.service.inquire.bean.InquireSkuTestingMessage;
import com.coffee.sku.service.inquire.dao.InquireSalesInformationDao;
import com.coffee.sku.service.inquire.dao.InquireSkuContentDao;
import com.coffee.sku.service.inquire.dao.InquireSkuTestingMessageDao;
import com.coffee.sku.service.sku.bean.Sku;
import com.coffee.sku.service.sku.bean.SkuCategory;
import com.coffee.sku.service.sku.dao.SkuCategoryDao;
import com.coffee.sku.service.sku.dao.SkuDao;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Value;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;


@DubboService(dynamic = true)
public class InquireOrderTestingServiceImpl implements InquireOrderTestingService {

    @Value("${TAG}")
    private String environment;
    @Resource
    private InquireOrderTestingDao inquireOrderTestingDao;
    @Resource
    private InquireOrderDao inquireOrderDao;
    @Resource
    private InquireSalesInformationDao inquireSalesInformationDao;
    @Resource
    private InquireSkuTestingMessageDao inquireSkuTestingMessageDao;
    @Resource
    private InquireOrderLogDao inquireOrderLogDao;
    @Resource
    private SupplierDao supplierDao;
    @Resource
    private MerchantDao merchantDao;
    @Resource
    private SkuCategoryDao skuCategoryDao;
    @Resource
    private SupplierSystemDeployDao supplierSystemDeployDao;
    @Resource
    private SkuDao skuDao;
    @Resource
    private InquireSkuContentDao inquireSkuContentDao;
    @Resource
    private OrderDao orderDao;


    @Override
    public Page<InquireOrderTestingResult> getPager(InquireOrderTestingQuery param, PagerInfo pr) {
        Page<InquireOrderTestingResult> pager = new Page<InquireOrderTestingResult>(pr.getStart(), pr.getPageSize());
        Integer count = inquireOrderTestingDao.count(param);
        pager.setTotalPage(count);
        if (count > 0) {
            List<InquireOrderTesting> list = inquireOrderTestingDao.page(param, pr.getStart(), pr.getPageSize());
            pager.setData(DTOUtils.convertList(list, InquireOrderTestingResult.class));
        }
        return pager;
    }

    @Override
    public Page<InquireOrderTestingResult> getPagerByReq(InquireOrderTestingReq param, PagerInfo pr) {
        Page<InquireOrderTestingResult> pager = new Page<InquireOrderTestingResult>(pr.getStart(), pr.getPageSize());
        Integer count = inquireOrderTestingDao.countByReq(param);
        pager.setTotalPage(count);
        if (count > 0) {
            List<InquireOrderTestingResult> list = inquireOrderTestingDao.pageByReq(param, pr.getStart(), pr.getPageSize());
            for (InquireOrderTestingResult inquireOrderTestingResult : list) {
                SkuCategory skuCategory = skuCategoryDao.findById(inquireOrderTestingResult.getCategoryId());
                if (skuCategory != null) {
                    inquireOrderTestingResult.setCategoryName(skuCategory.getName());
                }
                //获取商品详情
                InquireSalesInformation inquireSalesInformation = inquireSalesInformationDao.findById(inquireOrderTestingResult.getInquireSalesInformationId());
                if (inquireSalesInformation != null) {
                    inquireOrderTestingResult.setSpecifications(inquireSalesInformation.getSpecifications());
                    inquireOrderTestingResult.setUnit(inquireSalesInformation.getUnit());
                }
                SupplierSystemDeployQuery supplierSystemDeployQuery = new SupplierSystemDeployQuery();
                supplierSystemDeployQuery.setSupplierId(inquireOrderTestingResult.getSupplierId());
                supplierSystemDeployQuery.setType(OrderTypeEnum.TESTING.getCode());
                supplierSystemDeployQuery.setStatus(inquireOrderTestingResult.getTestingStatus());
                SupplierSystemDeploy supplierSystemDeploy = supplierSystemDeployDao.findFirst(supplierSystemDeployQuery);
                if (supplierSystemDeploy != null) {
                    inquireOrderTestingResult.setExpirationTime(getExpireTime(supplierSystemDeploy.getUnit(), supplierSystemDeploy.getDetails(), inquireOrderTestingResult.getCreateTime()));
                }
            }
            pager.setData(list);
        }
        return pager;
    }


    public Date getExpireTime(String uint, Integer details, Date date) {
        if (SystemDeployTimeEnum.DAY.getCode().equals(uint)) {
            return DateUtil.addDays(date, details);
        } else if (SystemDeployTimeEnum.HOUR.getCode().equals(uint)) {
            return DateUtil.addHour(date, details);
        } else if (SystemDeployTimeEnum.HOUR.getCode().equals(uint)) {
            return DateUtil.addHour(date, details);
        } else if (SystemDeployTimeEnum.MINUTE.getCode().equals(uint)) {
            return DateUtil.addMinutes(date, details);
        }
        return null;
    }

    @Override
    public Integer count(InquireOrderTestingQuery param) {
        Integer count = inquireOrderTestingDao.count(param);
        return count;
    }

    @Override
    public InquireOrderTestingResult getDetailById(Integer id, Integer supplierId) {
        InquireOrderTestingResult inquireOrderTestingResult = new InquireOrderTestingResult();
        InquireOrderTesting inquireOrder = inquireOrderTestingDao.findByIdAndSupplierId(id, supplierId);
        BeanUtilExt.copyProperties(inquireOrderTestingResult, inquireOrder);
        List<InquireOrderLog> inquireOrderLogs = inquireOrderLogDao.findByOrderId(inquireOrder.getId(), OrderTypeEnum.TESTING.getCode());
        if (inquireOrderLogs != null && inquireOrderLogs.size() > 0) {
            List<InquireOrderLogResult> inquireOrderLogResults = DTOUtils.convertList(inquireOrderLogs, InquireOrderLogResult.class);
            Map<String, List<InquireOrderLogResult>> stringListMap = inquireOrderLogResults.stream().collect(Collectors.groupingBy(InquireOrderLogResult::getDescribePeople));
            inquireOrderTestingResult.setInquireOrderLogResults(stringListMap);
        }
        //获取商品详情
        InquireSalesInformation inquireSalesInformation = inquireSalesInformationDao.findById(inquireOrder.getInquireSalesInformationId());
        if (inquireSalesInformation != null) {
            InquireSalesInformationResult inquireSalesInformationResult = new InquireSalesInformationResult();
            BeanUtilExt.copyProperties(inquireSalesInformationResult, inquireSalesInformation);
            inquireOrderTestingResult.setInquireSalesInformationResult(inquireSalesInformationResult);
        }
        return inquireOrderTestingResult;
    }

    @Override
    public InquireOrderTestingResult getDetailByIdAndMerchantId(Integer id, Integer merchantId) {
        InquireOrderTestingResult inquireOrderTestingResult = new InquireOrderTestingResult();
        InquireOrderTesting inquireOrderTesting = inquireOrderTestingDao.findById(id);
        if (inquireOrderTesting == null) {
            return inquireOrderTestingResult;
        }
        BeanUtilExt.copyProperties(inquireOrderTestingResult, inquireOrderTesting);
        InquireOrder inquireOrder = inquireOrderDao.findById(inquireOrderTesting.getInquireOrderId());
        Sku sku = skuDao.findById(inquireOrder.getSkuId());
        if (sku != null) {
            inquireOrderTestingResult.setTitle(sku.getTitle());
            SkuCategory skuCategory = skuCategoryDao.findById(sku.getCategoryId());
            if (skuCategory != null) {
                inquireOrderTestingResult.setCategoryName(skuCategory.getName());
            }
        }
        InquireSkuContent inquireSkuContent = inquireSkuContentDao.findById(inquireOrder.getInquireSkuId());
        if (inquireSkuContent != null) {
            inquireOrderTestingResult.setCover(inquireSkuContent.getCover());
        }
        //获取商品详情
        InquireSalesInformation inquireSalesInformation = inquireSalesInformationDao.findById(inquireOrder.getInquireSalesInformationId());
        if (inquireSalesInformation != null) {
            inquireOrderTestingResult.setSpecifications(inquireSalesInformation.getSpecifications());
            inquireOrderTestingResult.setUnit(inquireSalesInformation.getUnit());
        }
        SupplierSystemDeployQuery supplierSystemDeployQuery = new SupplierSystemDeployQuery();
        supplierSystemDeployQuery.setSupplierId(inquireOrder.getSupplierId());
        supplierSystemDeployQuery.setType(OrderTypeEnum.TESTING.getCode());
        supplierSystemDeployQuery.setStatus(inquireOrderTestingResult.getTestingStatus());
        SupplierSystemDeploy supplierSystemDeploy = supplierSystemDeployDao.findFirst(supplierSystemDeployQuery);
        if (supplierSystemDeploy != null) {
            inquireOrderTestingResult.setExpirationTime(getExpireTime(supplierSystemDeploy.getUnit(), supplierSystemDeploy.getDetails(), inquireOrderTesting.getCreateTime()));
        }
        return inquireOrderTestingResult;
    }

    @Override
    public List<InquireOrderTestingResult> getList(InquireOrderTestingQuery param, PagerInfo pr) {
        List<InquireOrderTesting> list = inquireOrderTestingDao.page(param, pr.getStart(), pr.getPageSize());
        return DTOUtils.convertList(list, InquireOrderTestingResult.class);
    }

    @Override
    public List<InquireOrderTestingResult> getList(InquireOrderTestingQuery param) {
        List<InquireOrderTesting> list = inquireOrderTestingDao.page(param, 0, Integer.MAX_VALUE);
        return DTOUtils.convertList(list, InquireOrderTestingResult.class);
    }

    @Override
    public List<InquireOrderTestingResult> getList() {
        InquireOrderTestingQuery param = new InquireOrderTestingQuery();
        List<InquireOrderTesting> list = inquireOrderTestingDao.page(param, 0, Integer.MAX_VALUE);
        return DTOUtils.convertList(list, InquireOrderTestingResult.class);
    }


    @Override
    public void delete(Integer id) {
        inquireOrderTestingDao.deleteById(id);
    }

    @Override
    public Map<Integer, InquireOrderTestingResult> getItemMap(Set<Integer> idSet) {
        Map<Integer, InquireOrderTestingResult> map = new HashMap<Integer, InquireOrderTestingResult>();
        List<InquireOrderTesting> list = inquireOrderTestingDao.findByIds(StringUtil.setToList(idSet));
        List<InquireOrderTestingResult> resultList = DTOUtils.convertList(list, InquireOrderTestingResult.class);
        for (InquireOrderTestingResult item : resultList) {
            map.put(item.getId(), item);
        }
        return map;
    }

    @Override
    public Map<Integer, InquireOrderTestingResult> getItemMap() {
        Map<Integer, InquireOrderTestingResult> map = new HashMap<Integer, InquireOrderTestingResult>();
        InquireOrderTestingQuery param = new InquireOrderTestingQuery();
        List<InquireOrderTesting> list = inquireOrderTestingDao.page(param, 0, Integer.MAX_VALUE);
        List<InquireOrderTestingResult> resultList = DTOUtils.convertList(list, InquireOrderTestingResult.class);
        for (InquireOrderTestingResult item : resultList) {
            map.put(item.getId(), item);
        }
        return map;
    }

    @Override
    public OrderResult createTestingOrder(CreateTestingOrderReq req) throws BusinessException {
        Integer inquireOrderId = req.getInquireOrderId();
        Integer inquireOrderTestingId = req.getId();
        Integer inquireSkuTestingMessageId = req.getInquireSkuTestingMessageId();
        String type = req.getType();
        Integer userId = req.getUserId();
        if (inquireOrderTestingId != null) {
            InquireOrderTesting inquireOrderTesting = inquireOrderTestingDao.findById(inquireOrderTestingId);
            ValidateBusinessException.assertNonNull(inquireOrderTesting, ExceptionEnum.ERROR_1829);
            ValidateBusinessException.assertTrue(SkuOrderStatusEnum.WAITING.getCode().equals(inquireOrderTesting.getTestingStatus()), ExceptionEnum.ERROR_1832);
            OrderResult orderResult = new OrderResult();
            orderResult.setOutOrderId(environment + OrderTypeEnum.TESTING.getCode() + "-" + inquireOrderTesting.getId());
            orderResult.setMerchantId(req.getUserId());
            orderResult.setOrderType(OrderTypeEnum.TESTING.getCode());
            orderResult.setTotalPrice(inquireOrderTesting.getTestingPrice());
            orderResult.setPayPrice(inquireOrderTesting.getTestingPrice());
            return orderResult;
        }
        String name = null;
        ValidateBusinessException.assertIdNotNull(inquireOrderId, ExceptionEnum.ERROR_1812);
        InquireOrder inquireOrder = inquireOrderDao.findByIdForUpdate(inquireOrderId);
        ValidateBusinessException.assertNonNull(inquireOrder, ExceptionEnum.ERROR_1813);
        InquireOrderTesting byInquireOrderId = inquireOrderTestingDao.findByInquireOrderId(inquireOrderId);
        ValidateBusinessException.assertNull(byInquireOrderId, ExceptionEnum.ERROR_1836);
        InquireSkuTestingMessage inquireSkuTestingMessage = inquireSkuTestingMessageDao.findById(inquireSkuTestingMessageId);
        ValidateBusinessException.assertNonNull(inquireSkuTestingMessage, ExceptionEnum.ERROR_1824);
        ValidateBusinessException.assertTrue(inquireOrder.getInquireSkuId().equals(inquireSkuTestingMessage.getInquireSkuId()), ExceptionEnum.ERROR_1824);
        if ((RoleTypeEnum.MERCHANT.getCode().equals(type) && inquireOrder.getMerchantId().equals(userId))) {
            Merchant merchant = merchantDao.findById(userId);
            name = merchant.getName();
        } else if ((RoleTypeEnum.SUPPLIER.getCode().equals(type) && inquireOrder.getSupplierId().equals(userId))) {
            Supplier supplier = supplierDao.findById(userId);
            name = supplier.getName();
        } else {
            throw new BusinessException(ExceptionEnum.ERROR_1823.getCode(), ExceptionEnum.ERROR_1823.getMessage());
        }
        InquireOrderTesting param = new InquireOrderTesting();
        param.setInquireOrderId(inquireOrderId);
        param.setTestingCompany(inquireSkuTestingMessage.getTestingCompany());
        if ("Y".equals(inquireSkuTestingMessage.getIsFree())) {
            throw new BusinessException(ExceptionEnum.ERROR_1849.getCode(), ExceptionEnum.ERROR_1849.getMessage());
        } else {
            param.setTestingPrice(inquireSkuTestingMessage.getTestingPrice());
            param.setTestingStatus(SkuOrderStatusEnum.WAITING.getCode());
        }
        param.setCreateTime(new Date());
        param.setMerchantId(inquireOrder.getMerchantId());
        inquireOrderTestingDao.insert(param);
        addInquireOrderLog(param.getId(), "生成检测订单", "买家", name);
        OrderResult orderResult = new OrderResult();
        orderResult.setOutOrderId(environment + OrderTypeEnum.TESTING.getCode() + "-" + param.getId());
        orderResult.setMerchantId(inquireOrder.getMerchantId());
        orderResult.setOrderType(OrderTypeEnum.TESTING.getCode());
        orderResult.setTotalPrice(param.getTestingPrice());
        orderResult.setPayPrice(param.getTestingPrice());
        return orderResult;
    }

    @Override
    public void cancelOrder(Integer id, Integer merchantId) throws BusinessException {
        InquireOrderTesting inquireOrderTesting = inquireOrderTestingDao.findByIdAndMerchantId(id, merchantId);
        ValidateBusinessException.assertNonNull(inquireOrderTesting, ExceptionEnum.ERROR_1829);
        ValidateBusinessException.assertFalse(SkuOrderStatusEnum.SUCCESS.getCode().equals(inquireOrderTesting.getTestingStatus()), ExceptionEnum.ERROR_1830);
        ValidateBusinessException.assertFalse(SkuOrderStatusEnum.PAY.getCode().equals(inquireOrderTesting.getTestingStatus()), ExceptionEnum.ERROR_1832);
        InquireOrderTesting param = new InquireOrderTesting();
        param.setId(id);
        param.setTestingStatus(SkuOrderStatusEnum.CANCEL.getCode());
        inquireOrderTestingDao.updateById(param);
        Merchant merchant = merchantDao.findById(merchantId);
        addInquireOrderLog(inquireOrderTesting.getId(), "取消检测订单", "买家", merchant.getName());
    }

    @Override
    public void uploadReport(Integer id, String cover, Integer supplierId) throws BusinessException {
        InquireOrderTesting inquireOrderTesting = inquireOrderTestingDao.findByIdAndSupplierId(id, supplierId);
        ValidateBusinessException.assertNonNull(inquireOrderTesting, ExceptionEnum.ERROR_1829);
        ValidateBusinessException.assertFalse(SkuOrderStatusEnum.SUCCESS.getCode().equals(inquireOrderTesting.getTestingStatus()), ExceptionEnum.ERROR_1830);
        ValidateBusinessException.assertTrue(SkuOrderStatusEnum.PAY.getCode().equals(inquireOrderTesting.getTestingStatus()), ExceptionEnum.ERROR_1831);
        InquireOrderTesting param = new InquireOrderTesting();
        param.setId(id);
        param.setTestingStatus(SkuOrderStatusEnum.SUCCESS.getCode());
        param.setTestingResult(cover);
        inquireOrderTestingDao.updateById(param);
        Supplier supplier = supplierDao.findById(supplierId);
        addInquireOrderLog(inquireOrderTesting.getId(), "上传检测报告", "卖方", supplier.getName());
    }

    @Override
    public void uploadReportByMerchantId(Integer id, String cover, Integer merchantId) throws BusinessException {
        InquireOrderTesting inquireOrderTesting = inquireOrderTestingDao.findByIdAndMerchantId(id, merchantId);
        ValidateBusinessException.assertNonNull(inquireOrderTesting, ExceptionEnum.ERROR_1829);
        ValidateBusinessException.assertFalse(SkuOrderStatusEnum.SUCCESS.getCode().equals(inquireOrderTesting.getTestingStatus()), ExceptionEnum.ERROR_1830);
        ValidateBusinessException.assertTrue(SkuOrderStatusEnum.PAY.getCode().equals(inquireOrderTesting.getTestingStatus()), ExceptionEnum.ERROR_1831);
        InquireOrderTesting param = new InquireOrderTesting();
        param.setId(id);
        param.setTestingStatus(SkuOrderStatusEnum.SUCCESS.getCode());
        param.setTestingResult(cover);
        inquireOrderTestingDao.updateById(param);
        Merchant merchant = merchantDao.findById(merchantId);
        addInquireOrderLog(inquireOrderTesting.getId(), "上传检测报告", "买家", merchant.getName());
    }

    @Override
    public List<InquireSkuTestingMessageResult> getInquireSkuTestingMessageResult(Integer inquireOrderId) throws BusinessException {
        ValidateBusinessException.assertIdNotNull(inquireOrderId, ExceptionEnum.ERROR_1812);
        InquireOrder inquireOrder = inquireOrderDao.findByIdForUpdate(inquireOrderId);
        ValidateBusinessException.assertNonNull(inquireOrder, ExceptionEnum.ERROR_1813);
        InquireSkuTestingMessageQuery param = new InquireSkuTestingMessageQuery();
        param.setInquireSkuId(inquireOrder.getInquireSkuId());
        param.setIsFree("N");
        List<InquireSkuTestingMessage> list = inquireSkuTestingMessageDao.list(param);
        if (list == null || list.size() <= 0) {
            return null;
        }

        return DTOUtils.convertList(list, InquireSkuTestingMessageResult.class);
    }

    void addInquireOrderLog(Integer orderId, String describe, String describePeople, String platformName) {
        InquireOrderLog inquireOrderLog = new InquireOrderLog();
        inquireOrderLog.setOrderId(orderId);
        inquireOrderLog.setDescribe(describe);
        inquireOrderLog.setDescribePeople(describePeople);
        inquireOrderLog.setPlatformName(platformName);
        inquireOrderLog.setCreateTime(new Date());
        inquireOrderLog.setType(OrderTypeEnum.TESTING.getCode());
        inquireOrderLogDao.insert(inquireOrderLog);
    }


}
